package com.micro.play.internet.audio.book.extension.util;

import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * http工具类
 *
 * @author guochaohui
 * @return
 * @date 2020-01-21 10:49
 */
public class HttpUtil {

    private static final Logger LOG = LoggerFactory.getLogger(HttpUtil.class);
    private static final String CHARSET = "UTF-8";
    private static volatile CloseableHttpClient httpClient = null;

    // http最大请求数量
    private static int HTTP_MAX_TOTAL = 200;
    // http最大并发数量
    private static int HTTP_MAX_PER_ROUTE = 100;
    // 获取连接超时时间
    private static int HTTP_REQUEST_TIME_OUT = 500;
    // 创建连接超时时间
    private static int HTTP_CONNECTION_TIME_OUT = 2000;
    // 数据处理超时时间
    private static int HTTP_SOCKET_TIME_OUT = 30000;

    /**
     * 初始化连接池
     */
    private static synchronized void initHttpClient() {
        if (httpClient == null) {
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", SSLConnectionSocketFactory.getSocketFactory())
                    .build();
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(HTTP_MAX_TOTAL);
            cm.setDefaultMaxPerRoute(HTTP_MAX_PER_ROUTE);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(HTTP_SOCKET_TIME_OUT)
                    .setConnectTimeout(HTTP_CONNECTION_TIME_OUT)
                    .setConnectionRequestTimeout(HTTP_REQUEST_TIME_OUT)
                    .build();
            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(requestConfig)
                    .setConnectionManager(cm)
                    .setConnectionManagerShared(true)
                    .build();
        }
        return;
    }

    /**
     * http post请求
     *
     * @param url    请求地址
     * @param params 请求参数
     * @return
     */
    public static String post(String url, Map<String, Object> params) {
        return post(url, params, CHARSET);
    }

    /**
     * http post请求
     *
     * @param url     请求地址
     * @param params  请求参数
     * @param charSet 编码
     * @return
     */
    public static String post(String url, Map<String, Object> params, String charSet) {
        String body = null;
        try {
            initHttpClient();
            HttpPost httpPost = new HttpPost(url);
            List<NameValuePair> parameters = new ArrayList<NameValuePair>();
            if (MapUtils.isNotEmpty(params)) {
                for (Iterator<String> iterator = params.keySet().iterator(); iterator.hasNext(); ) {
                    String key = iterator.next();
                    parameters.add(new BasicNameValuePair(key, params.get(key).toString()));
                }
            }
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(parameters, charSet);
            httpPost.setEntity(uefEntity);
            CloseableHttpResponse response = httpClient.execute(httpPost);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    body = EntityUtils.toString(entity, charSet);
                }
            } finally {
                response.close();
            }
        } catch (Throwable e) {
            LOG.error("httpClient post error. ", e);
        }
        return body;
    }

    /**
     * http post请求
     *
     * @param url 请求地址
     * @return
     */
    public static String get(String url) {
        return get(url, CHARSET);
    }

    /**
     * http post请求
     *
     * @param url     请求地址
     * @param charSet 编码
     * @return
     */
    public static String get(String url, String charSet) {
        String body = null;
        try {
            initHttpClient();
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    body = EntityUtils.toString(entity, charSet);
                }
            } finally {
                response.close();
            }
        } catch (Throwable e) {
            LOG.error("httpClient post error. ", e);
        }
        return body;
    }

}
